package com.yxt.gateway.filter;

import com.alibaba.fastjson.JSON;
import com.yxt.common.exception.BizCodeEnume;
import com.yxt.common.exception.UnauthorizedException;
import com.yxt.common.utils.JwtUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.RequestPath;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.security.jwt.Jwt;
import org.springframework.security.jwt.JwtHelper;
import org.springframework.security.jwt.crypto.sign.RsaVerifier;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
import java.util.stream.Collectors;

//认证授权组合过滤器
@Component
@Slf4j
public class AuthFilter implements GlobalFilter, Ordered {

    //公钥
    public static final String PUBLIC_KEY = "public.key";

    @Value("#{'${whiteList}'.split(',')}")
    private String[] whiteList;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();

        RequestPath path = request.getPath();

        //白名单一律放行
        PathMatcher matcher = new AntPathMatcher();
        if(whiteList!=null){
            List<String> whiteLists = Arrays.asList(whiteList);
            for(String item: whiteLists)
            {
                if(matcher.match(item,path.toString())){
                    return chain.filter(exchange);
                }
            }
        }

        //2.获取响应对象
        ServerHttpResponse response = exchange.getResponse();

        String authorization = request.getHeaders().get("Authorization").get(0);

        String tokenStr = StringUtils.substring("Bearer ", 0);

        String token = StringUtils.substringAfter(authorization, " ");

        Jwt jwt = null;
        try {
            jwt = JwtHelper.decodeAndVerify(token, new RsaVerifier(getPubKey()));
        } catch (Exception e) {
            e.printStackTrace();
            log.error("非法的凭证");
            throw new UnauthorizedException(BizCodeEnume.UNAUTHORIZED_EXCEPTION);

        }

        String claims = jwt.getClaims();
        HashMap hashMap = JSON.parseObject(claims, HashMap.class);

        List<String> authorities = (List<String>) hashMap.get("authorities");



        for(String item: authorities)
        {
            if(matcher.match(item,path.toString())){
                return chain.filter(exchange);
            }
        }

        log.error("没有权限访问系统");
        throw new UnauthorizedException(BizCodeEnume.UNAUTHORIZED_EXCEPTION);
    }

    @Override
    public int getOrder() {
        return 2;
    }

    private String getPubKey() {
        Resource resource = new ClassPathResource(PUBLIC_KEY);
        try {
            InputStreamReader inputStreamReader = new InputStreamReader(resource.getInputStream());
            BufferedReader br = new BufferedReader(inputStreamReader);
            return br.lines().collect(Collectors.joining("\n"));
        } catch (IOException ioe) {
            return null;
        }
    }
}
